cd ../..
/Users/shanekercheval/repos/data-science-template
%run "source/config/notebook_settings.py"
file_name = 'artifacts/models/experiments/multi-model-BayesSearchCV-2022-03-19-14-44-37.yaml'
results = hlp.sklearn_eval.MLExperimentResults.from_yaml_file(yaml_file_name = file_name)
results.best_score
0.774092779234226
results.best_params
{'model': 'LogisticRegression()',
'C': 0.13184996310179986,
'imputer': "SimpleImputer(strategy='median')",
'scaler': 'StandardScaler()',
'pca': 'None',
'encoder': 'OneHotEncoder()'}
# Best model from each model-type.
df = results.to_formatted_dataframe(return_style=False, include_rank=True)
df["model_rank"] = df.groupby("model")["roc_auc Mean"].rank(method="first", ascending=False)
df.query('model_rank == 1')
| rank | roc_auc Mean | roc_auc 95CI.LO | roc_auc 95CI.HI | model | C | max_features | max_depth | n_estimators | min_samples_split | min_samples_leaf | max_samples | criterion | learning_rate | min_child_weight | subsample | colsample_bytree | colsample_bylevel | reg_alpha | reg_lambda | imputer | scaler | pca | encoder | model_rank | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5 | 1 | 0.77 | 0.73 | 0.82 | LogisticRegression() | 0.13 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | SimpleImputer(strategy='median') | StandardScaler() | None | OneHotEncoder() | 1.00 |
| 18 | 2 | 0.77 | 0.72 | 0.81 | RandomForestClassifier() | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | SimpleImputer() | None | None | OneHotEncoder() | 1.00 |
| 7 | 4 | 0.76 | 0.72 | 0.80 | LinearSVC() | 0.28 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | SimpleImputer(strategy='most_frequent') | MinMaxScaler() | PCA('mle') | OneHotEncoder() | 1.00 |
| 16 | 6 | 0.76 | 0.70 | 0.82 | ExtraTreesClassifier() | NaN | 0.68 | 30.00 | 1659.00 | 25.00 | 11.00 | 0.78 | gini | NaN | NaN | NaN | NaN | NaN | NaN | NaN | SimpleImputer() | None | PCA('mle') | OneHotEncoder() | 1.00 |
| 28 | 9 | 0.75 | 0.71 | 0.80 | XGBClassifier() | NaN | NaN | 5.00 | 1246.00 | NaN | NaN | NaN | NaN | 0.02 | 15.00 | 0.96 | 0.69 | 0.52 | 0.24 | 1.22 | SimpleImputer(strategy='median') | None | None | OneHotEncoder() | 1.00 |
results.to_formatted_dataframe(return_style=True,
include_rank=True,
num_rows=1000)
| rank | roc_auc Mean | roc_auc 95CI.LO | roc_auc 95CI.HI | model | C | max_features | max_depth | n_estimators | min_samples_split | min_samples_leaf | max_samples | criterion | learning_rate | min_child_weight | subsample | colsample_bytree | colsample_bylevel | reg_alpha | reg_lambda | imputer | scaler | pca | encoder |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 0.774 | 0.730 | 0.818 | LogisticRegression() | 0.132 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | StandardScaler() | None | OneHotEncoder() |
| 2 | 0.767 | 0.720 | 0.814 | RandomForestClassifier() | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | None | None | OneHotEncoder() |
| 3 | 0.763 | 0.725 | 0.802 | LogisticRegression() | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | StandardScaler() | None | OneHotEncoder() |
| 4 | 0.761 | 0.720 | 0.803 | LinearSVC() | 0.281 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='most_frequent') | MinMaxScaler() | PCA('mle') | OneHotEncoder() |
| 5 | 0.761 | 0.697 | 0.825 | LogisticRegression() | 0.001 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | MinMaxScaler() | None | OneHotEncoder() |
| 6 | 0.760 | 0.701 | 0.819 | ExtraTreesClassifier() | <NA> | 0.685 | 30.000 | 1,659.000 | 25.000 | 11.000 | 0.781 | gini | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | None | PCA('mle') | OneHotEncoder() |
| 7 | 0.755 | 0.714 | 0.796 | RandomForestClassifier() | <NA> | 0.599 | 70.000 | 1,858.000 | 39.000 | 22.000 | 0.851 | gini | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='most_frequent') | None | None | OneHotEncoder() |
| 8 | 0.753 | 0.716 | 0.791 | RandomForestClassifier() | <NA> | 0.303 | 81.000 | 1,063.000 | 15.000 | 27.000 | 0.502 | gini | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | None | None | OneHotEncoder() |
| 9 | 0.753 | 0.710 | 0.796 | XGBClassifier() | <NA> | <NA> | 5.000 | 1,246.000 | <NA> | <NA> | <NA> | <NA> | 0.023 | 15.000 | 0.956 | 0.695 | 0.519 | 0.242 | 1.221 | SimpleImputer(strategy='median') | None | None | OneHotEncoder() |
| 10 | 0.752 | 0.698 | 0.805 | ExtraTreesClassifier() | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | None | None | OneHotEncoder() |
| 11 | 0.751 | 0.721 | 0.781 | LinearSVC() | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | StandardScaler() | None | OneHotEncoder() |
| 12 | 0.751 | 0.714 | 0.788 | RandomForestClassifier() | <NA> | 0.323 | 76.000 | 1,619.000 | 31.000 | 36.000 | 0.595 | gini | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | None | None | OneHotEncoder() |
| 13 | 0.749 | 0.698 | 0.801 | XGBClassifier() | <NA> | <NA> | 1.000 | 1,974.000 | <NA> | <NA> | <NA> | <NA> | 0.024 | 4.000 | 0.543 | 0.620 | 0.876 | 0.034 | 1.445 | SimpleImputer() | None | PCA('mle') | OneHotEncoder() |
| 14 | 0.749 | 0.706 | 0.792 | ExtraTreesClassifier() | <NA> | 0.408 | 87.000 | 1,423.000 | 25.000 | 19.000 | 0.989 | entropy | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='most_frequent') | None | PCA('mle') | CustomOrdinalEncoder() |
| 15 | 0.747 | 0.694 | 0.799 | ExtraTreesClassifier() | <NA> | 0.710 | 15.000 | 1,493.000 | 33.000 | 27.000 | 0.914 | gini | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='most_frequent') | None | PCA('mle') | OneHotEncoder() |
| 16 | 0.746 | 0.708 | 0.785 | XGBClassifier() | <NA> | <NA> | 3.000 | 931.000 | <NA> | <NA> | <NA> | <NA> | 0.029 | 7.000 | 0.930 | 0.817 | 0.898 | 0.000 | 2.733 | SimpleImputer(strategy='most_frequent') | None | None | OneHotEncoder() |
| 17 | 0.746 | 0.716 | 0.776 | LogisticRegression() | 23.327 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | StandardScaler() | None | OneHotEncoder() |
| 18 | 0.744 | 0.698 | 0.790 | ExtraTreesClassifier() | <NA> | 0.328 | 5.000 | 1,047.000 | 23.000 | 43.000 | 0.957 | entropy | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | None | PCA('mle') | OneHotEncoder() |
| 19 | 0.744 | 0.709 | 0.779 | RandomForestClassifier() | <NA> | 0.567 | 38.000 | 1,060.000 | 19.000 | 41.000 | 0.656 | entropy | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | None | PCA('mle') | OneHotEncoder() |
| 20 | 0.742 | 0.686 | 0.798 | XGBClassifier() | <NA> | <NA> | 10.000 | 1,146.000 | <NA> | <NA> | <NA> | <NA> | 0.025 | 14.000 | 0.771 | 0.548 | 0.748 | 0.093 | 1.892 | SimpleImputer(strategy='median') | None | PCA('mle') | OneHotEncoder() |
| 21 | 0.738 | 0.686 | 0.790 | XGBClassifier() | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | None | None | OneHotEncoder() |
| 22 | 0.736 | 0.695 | 0.777 | ExtraTreesClassifier() | <NA> | 0.740 | 14.000 | 1,645.000 | 5.000 | 43.000 | 0.741 | entropy | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='most_frequent') | None | PCA('mle') | CustomOrdinalEncoder() |
| 23 | 0.734 | 0.695 | 0.773 | RandomForestClassifier() | <NA> | 0.770 | 70.000 | 1,570.000 | 16.000 | 39.000 | 0.910 | entropy | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='most_frequent') | None | None | CustomOrdinalEncoder() |
| 24 | 0.730 | 0.702 | 0.758 | LogisticRegression() | 0.000 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | StandardScaler() | None | CustomOrdinalEncoder() |
| 25 | 0.727 | 0.690 | 0.765 | LinearSVC() | 0.361 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | MinMaxScaler() | PCA('mle') | CustomOrdinalEncoder() |
| 26 | 0.727 | 0.689 | 0.765 | LinearSVC() | 0.746 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | MinMaxScaler() | None | CustomOrdinalEncoder() |
| 27 | 0.726 | 0.697 | 0.755 | LogisticRegression() | 0.000 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer(strategy='median') | StandardScaler() | PCA('mle') | CustomOrdinalEncoder() |
| 28 | 0.714 | 0.679 | 0.749 | XGBClassifier() | <NA> | <NA> | 4.000 | 1,181.000 | <NA> | <NA> | <NA> | <NA> | 0.067 | 7.000 | 0.557 | 0.763 | 0.592 | 0.001 | 2.984 | SimpleImputer(strategy='median') | None | PCA('mle') | CustomOrdinalEncoder() |
| 29 | 0.701 | 0.669 | 0.733 | LinearSVC() | 10.021 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | MinMaxScaler() | PCA('mle') | CustomOrdinalEncoder() |
| 30 | 0.681 | 0.646 | 0.717 | LinearSVC() | 0.000 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | StandardScaler() | None | CustomOrdinalEncoder() |
results.to_formatted_dataframe(query='model == "RandomForestClassifier()"', include_rank=True)
| rank | roc_auc Mean | roc_auc 95CI.LO | roc_auc 95CI.HI | max_features | max_depth | n_estimators | min_samples_split | min_samples_leaf | max_samples | criterion | imputer | pca | encoder |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 0.767 | 0.720 | 0.814 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | SimpleImputer() | None | OneHotEncoder() |
| 2 | 0.755 | 0.714 | 0.796 | 0.599 | 70.000 | 1,858.000 | 39.000 | 22.000 | 0.851 | gini | SimpleImputer(strategy='most_frequent') | None | OneHotEncoder() |
| 3 | 0.753 | 0.716 | 0.791 | 0.303 | 81.000 | 1,063.000 | 15.000 | 27.000 | 0.502 | gini | SimpleImputer(strategy='median') | None | OneHotEncoder() |
| 4 | 0.751 | 0.714 | 0.788 | 0.323 | 76.000 | 1,619.000 | 31.000 | 36.000 | 0.595 | gini | SimpleImputer() | None | OneHotEncoder() |
| 5 | 0.744 | 0.709 | 0.779 | 0.567 | 38.000 | 1,060.000 | 19.000 | 41.000 | 0.656 | entropy | SimpleImputer() | PCA('mle') | OneHotEncoder() |
| 6 | 0.734 | 0.695 | 0.773 | 0.770 | 70.000 | 1,570.000 | 16.000 | 39.000 | 0.910 | entropy | SimpleImputer(strategy='most_frequent') | None | CustomOrdinalEncoder() |
results.to_formatted_dataframe(query='model == "LogisticRegression()"', include_rank=True)
| rank | roc_auc Mean | roc_auc 95CI.LO | roc_auc 95CI.HI | C | imputer | scaler | pca | encoder |
|---|---|---|---|---|---|---|---|---|
| 1 | 0.774 | 0.730 | 0.818 | 0.132 | SimpleImputer(strategy='median') | StandardScaler() | None | OneHotEncoder() |
| 2 | 0.763 | 0.725 | 0.802 | <NA> | SimpleImputer() | StandardScaler() | None | OneHotEncoder() |
| 3 | 0.761 | 0.697 | 0.825 | 0.001 | SimpleImputer(strategy='median') | MinMaxScaler() | None | OneHotEncoder() |
| 4 | 0.746 | 0.716 | 0.776 | 23.327 | SimpleImputer(strategy='median') | StandardScaler() | None | OneHotEncoder() |
| 5 | 0.730 | 0.702 | 0.758 | 0.000 | SimpleImputer(strategy='median') | StandardScaler() | None | CustomOrdinalEncoder() |
| 6 | 0.726 | 0.697 | 0.755 | 0.000 | SimpleImputer(strategy='median') | StandardScaler() | PCA('mle') | CustomOrdinalEncoder() |
results.plot_performance_across_trials(facet_by='model').show()
results.plot_performance_across_trials(query='model == "RandomForestClassifier()"').show()
results.plot_parameter_values_across_trials(query='model == "RandomForestClassifier()"').show()
# results.plot_scatter_matrix(query='model == "RandomForestClassifier()"',
# height=1000, width=1000).show()
results.plot_performance_numeric_params(query='model == "RandomForestClassifier()"',
height=800)
results.plot_parallel_coordinates(query='model == "RandomForestClassifier()"').show()
results.plot_performance_non_numeric_params(query='model == "RandomForestClassifier()"').show()
results.plot_score_vs_parameter(
query='model == "RandomForestClassifier()"',
parameter='max_features',
size='max_depth',
color='encoder',
)
# results.plot_parameter_vs_parameter(
# query='model == "XGBClassifier()"',
# parameter_x='colsample_bytree',
# parameter_y='learning_rate',
# size='max_depth'
# )
# results.plot_parameter_vs_parameter(
# query='model == "XGBClassifier()"',
# parameter_x='colsample_bytree',
# parameter_y='learning_rate',
# size='imputer'
# )
file_name = 'artifacts/models/experiments/multi-model-BayesSearchCV-2022-03-19-14-44-37_best_estimator.pkl'
best_estimator = hlp.utility.read_pickle(file_name)
x_test = pd.read_pickle('artifacts/data/processed/x_test.pkl')
x_test.head()
| checking_status | duration | credit_history | purpose | credit_amount | savings_status | employment | installment_commitment | personal_status | other_parties | residence_since | property_magnitude | age | other_payment_plans | housing | existing_credits | job | num_dependents | own_telephone | foreign_worker | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 521 | <0 | 18.00 | existing paid | radio/tv | 3190.00 | <100 | 1<=X<4 | 2.00 | female div/dep/mar | none | 2.00 | real estate | 24.00 | none | own | 1.00 | skilled | 1.00 | none | yes |
| 737 | <0 | 18.00 | existing paid | new car | 4380.00 | 100<=X<500 | 1<=X<4 | 3.00 | male single | none | 4.00 | car | 35.00 | none | own | 1.00 | unskilled resident | 2.00 | yes | yes |
| 740 | <0 | 24.00 | all paid | new car | 2325.00 | 100<=X<500 | 4<=X<7 | 2.00 | male single | none | 3.00 | car | 32.00 | bank | own | 1.00 | skilled | 1.00 | none | yes |
| 660 | >=200 | 12.00 | existing paid | radio/tv | 1297.00 | <100 | 1<=X<4 | 3.00 | male mar/wid | none | 4.00 | real estate | 23.00 | none | rent | 1.00 | skilled | 1.00 | none | yes |
| 411 | no checking | 33.00 | critical/other existing credit | used car | 7253.00 | <100 | 4<=X<7 | 3.00 | male single | none | 2.00 | car | 35.00 | none | own | 2.00 | high qualif/self emp/mgmt | 1.00 | yes | yes |
y_test = hlp.utility.read_pickle('artifacts/data/processed/y_test.pkl')
y_test[0:10]
array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
test_predictions = best_estimator.predict_proba(x_test)[:, 1]
test_predictions[0:10]
array([0.403314 , 0.49843118, 0.59686198, 0.32004122, 0.0857983 ,
0.35470202, 0.08364243, 0.45742452, 0.09325265, 0.13118732])
evaluator = hlp.sklearn_eval.TwoClassEvaluator(
actual_values=y_test,
predicted_scores=test_predictions,
score_threshold=0.37
)
evaluator.plot_actual_vs_predict_histogram()
evaluator.plot_confusion_matrix()
evaluator.all_metrics_df(return_style=True,
dummy_classifier_strategy=['prior', 'constant'],
round_by=3)
| Score | Dummy (prior) | Dummy (constant) | Explanation | |
|---|---|---|---|---|
| AUC | 0.800 | 0.500 | 0.500 | Area under the ROC curve (true pos. rate vs false pos. rate); ranges from 0.5 (purely random classifier) to 1.0 (perfect classifier) |
| True Positive Rate | 0.729 | 0.000 | 1.000 | 72.9% of positive instances were correctly identified.; i.e. 43 "Positive Class" labels were correctly identified out of 59 instances; a.k.a Sensitivity/Recall |
| True Negative Rate | 0.787 | 1.000 | 0.000 | 78.7% of negative instances were correctly identified.; i.e. 111 "Negative Class" labels were correctly identified out of 141 instances |
| False Positive Rate | 0.213 | 0.000 | 1.000 | 21.3% of negative instances were incorrectly identified as positive; i.e. 30 "Negative Class" labels were incorrectly identified as "Positive Class", out of 141 instances |
| False Negative Rate | 0.271 | 1.000 | 0.000 | 27.1% of positive instances were incorrectly identified as negative; i.e. 16 "Positive Class" labels were incorrectly identified as "Negative Class", out of 59 instances |
| Positive Predictive Value | 0.589 | 0.000 | 0.295 | When the model claims an instance is positive, it is correct 58.9% of the time; i.e. out of the 73 times the model predicted "Positive Class", it was correct 43 times; a.k.a precision |
| Negative Predictive Value | 0.874 | 0.705 | 0.000 | When the model claims an instance is negative, it is correct 87.4% of the time; i.e. out of the 127 times the model predicted "Negative Class", it was correct 111 times |
| F1 Score | 0.652 | 0.000 | 0.456 | The F1 score can be interpreted as a weighted average of the precision and recall, where an F1 score reaches its best value at 1 and worst score at 0. |
| Precision/Recall AUC | 0.647 | 0.295 | 0.295 | Precision/Recall AUC is calculated with `average_precision` which summarizes a precision-recall curve as the weighted mean of precisions achieved at each threshold. See sci-kit learn documentation for caveats. |
| Accuracy | 0.770 | 0.705 | 0.295 | 77.0% of instances were correctly identified |
| Error Rate | 0.230 | 0.295 | 0.705 | 23.0% of instances were incorrectly identified |
| % Positive | 0.295 | 0.295 | 0.295 | 29.5% of the data are positive; i.e. out of 200 total observations; 59 are labeled as "Positive Class" |
| Total Observations | 200 | 200 | 200 | There are 200 total observations; i.e. sample size |
evaluator.plot_roc_auc_curve().show()
<Figure size 1000x618.034 with 0 Axes>
evaluator.plot_precision_recall_auc_curve().show()
evaluator.plot_threshold_curves(score_threshold_range=(0.1, 0.7)).show()
evaluator.plot_precision_recall_tradeoff(score_threshold_range=(0.1, 0.6)).show()
evaluator.calculate_lift_gain(return_style=True)
| Gain | Lift | |
|---|---|---|
| Percentile | ||
| 5 | 0.12 | 2.37 |
| 10 | 0.24 | 2.37 |
| 15 | 0.37 | 2.49 |
| 20 | 0.49 | 2.46 |
| 25 | 0.53 | 2.10 |
| 30 | 0.61 | 2.03 |
| 35 | 0.71 | 2.03 |
| 40 | 0.75 | 1.86 |
| 45 | 0.75 | 1.66 |
| 50 | 0.80 | 1.59 |
| 55 | 0.83 | 1.51 |
| 60 | 0.83 | 1.38 |
| 65 | 0.86 | 1.33 |
| 70 | 0.93 | 1.33 |
| 75 | 0.97 | 1.29 |
| 80 | 0.97 | 1.21 |
| 85 | 0.98 | 1.16 |
| 90 | 0.98 | 1.09 |
| 95 | 1.00 | 1.05 |
| 100 | 1.00 | 1.00 |